Server Communications Overview
Namespace: $GG.server
Related Topics
The Gig Games JavaScript library provides a framework for developing and managing multiplayer games. It includes core functionalities and various specialized services to handle game state, player interactions, event broadcasting, and more. This documentation covers the $GG
global object, detailing its public interface and usage guidelines.
Include In Html
<head>
...
<script src="https://launch.gig.game/api/js?key={API KEY HERE}"></script>
...
</head>
Three Parts of a Gig Game
Gig Games are designed with three primary components in mind:
1. Console:
- PC or Mobile Devices: In host-controlled games, this is typically a PC or laptop used to manage the game. In player-controlled games, this is the account owner's mobile device that can start and control games. Either way, this device manages the gameplay.
- Technologies: Developed with HTML, CSS, and JavaScript.
2. Optional Controller:
- Mobile Devices: Used by players invited to interact with the game.
- Technologies: Developed with HTML, CSS, and JavaScript.
- Optional Component: Not used in single-player games.
3. Optional Engine:
- Maintains Game State: Capable of preserving a game state over extended periods, independent of an active host PC.
- Network Efficiency: Reduces network lag by eliminating the need for round trips to a host console, providing a smoother gameplay experience.
- Technologies: Can be developed in .NET or JavaScript.
- Learn more about developing engines.
Controller and Host Console
SignalR is a library that makes it easy to add real-time web functionality to applications. This means it allows for instant messaging between the server and clients (like the game host and players) without needing to constantly refresh the page. It works by creating a persistent connection where the server can send messages to connected clients in real-time.
In our game application, SignalR is used to manage the communication between the host (the main game controller) and the players. We expose this functionality through the $GG.server
namespace, making it simple to broadcast events or capture events that are broadcast to us. Here's how it works in simple terms:
- Broadcast Events: The host can send messages or updates to all players or specific players. For example, starting a new game round or updating scores.
- Capture Events: Players can send messages back to the host or other players. For example, when a player makes a move or submits an answer.
When the game host starts a game, it is assigned to a specific communications server within our server farm and creates a unique game code. This game code is essential for routing messages correctly and is automatically handled by the $GG
library when included in your HTML.
Here’s a simplified flow:
- Host Initialization: The host starts the game, gets assigned to a server, and creates a game code.
- Player Join: Players enter this game code to join the game.
- Real-Time Communication: Using SignalR, the host and players can now send and receive real-time updates and messages.
The $GG
library manages this communication automatically, ensuring that all messages are sent to the correct devices using the game code. Authentication is built-in, ensuring that only the correct players and host (using their unique keys) can communicate within a game session.
Event Broadcast vs. Event Queueing
The $GG
library supports two types of message transmission:
- Event Broadcast: This sends messages in real-time but discards them if the connection is lost. This is useful for non-critical updates, such as real-time notifications or status updates, where missing a message or two does not significantly impact the game.
- Event Queueing: This ensures that messages are delivered even if the connection drops. If a player's connection is lost, messages are queued and automatically sent once the connection is restored.
Guaranteed message queueing ensures message delivery but can introduce delays due to queue management. Unguaranteed broadcasting offers lower latency and immediate delivery, making it ideal for real-time updates where occasional message loss is acceptable. This approach enhances game responsiveness without the performance impact of queuing.
Example of Message Events
Below is an example demonstrating how to send event between controlers and hosts.
Host Code Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Host Console</title>
<script src="https://launch.gig.game/api/js?key={YOUR_API_KEY_HERE}"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
const playerSelect = document.getElementById('playerSelect');
$GG.server.attachEvent("OnReady", () => {
console.log("Host is ready");
// Sync players with the host
$GG.server.syncPlayersToHost();
// Handle PlayerSessionSync event from us calling syncPlayersToHost
$GG.server.attachEvent('PlayerSessionSync', (options) => {
const players = options.players;
players.forEach(player => {
addPlayerToDropdown(player);
});
});
// Listen for player sessions starting. This is an automatic event from the framework when a controler starts.
$GG.server.attachEvent('PlayerSessionStart', (options, sourceType, source) => {
if (sourceType === "Player") {
addPlayerToDropdown(source);
alert(`Player joined: ${source.playerName}`);
}
});
// Listen for player sessions ending. This is an automatic event from the framework when a controler disconnects.
$GG.server.attachEvent('PlayerSessionEnd', (options, sourceType, source) => {
if (sourceType === "Player") {
removePlayerFromDropdown(source);
alert(`Player left: ${source.playerName}`);
}
});
// Listen for player actions. This is our custom event from the controller.
$GG.server.attachEvent('PlayerAction', (options, sourceType, source) => {
if (sourceType === "Player") {
alert(`Received from player ${source.playerName}: ${options.message}`);
}
});
});
function addPlayerToDropdown(player) {
const option = document.createElement('option');
option.value = player.playerKey;
option.textContent = player.playerName;
playerSelect.appendChild(option);
}
function removePlayerFromDropdown(player) {
const options = playerSelect.options;
for (let i = 0; i < options.length; i++) {
if (options[i].value === player.playerKey) {
playerSelect.remove(i);
break;
}
}
}
function sendMessageToPlayer() {
const selectedPlayerKey = playerSelect.value;
if (selectedPlayerKey) {
$GG.server.broadcastToPlayer(selectedPlayerKey, 'HostMessage', { message: 'Hello from Host!' });
} else {
alert('Please select a player to send a message.');
}
}
window.sendMessageToPlayer = sendMessageToPlayer;
});
</script>
</head>
<!-- gg-gamekey is assigned in Gig Game HUD when you create an app to develop -->
<!-- gg-hostkey is assigned in Gig Game HUD when you create an app to develop -->
<body
gg-gamekey="{Key Assigned on App Creation}"
gg-hostkey="{Key Assigned on App Creation}"
gg-language="en">
<h1>Host Console</h1>
<label for="playerSelect">Select Player:</label>
<select id="playerSelect">
<option value="">--Select a Player--</option>
</select>
<button onclick="sendMessageToPlayer()">Send Message to Selected Player</button>
<button onclick="sendMessageToPlayers()">Send Message to All Players</button>
</body>
</html>
Player Controller Code Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Player Controller</title>
<script src="https://launch.gig.game/api/js?key={YOUR_API_KEY_HERE}"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
$GG.server.attachEvent("OnReady", () => {
console.log("Controller is ready");
// Listen for messages from the host
$GG.server.attachEvent('HostMessage', (options, sourceType, source) => {
if (sourceType === "Host") {
alert(`Received from host: ${options.message}`);
}
});
});
function sendMessageToHost() {
$GG.server.broadcastToHost('PlayerAction', { message: 'Hello from Player!' });
}
window.sendMessageToHost = sendMessageToHost;
window.leaveGame = leaveGame;
});
</script>
</head>
<!-- gg-gamekey is assigned in Gig Game HUD when you create an app to develop -->
<!-- gg-playerkey is used for testing locally to simulate multiple players. 1 = Player 1, 2 = Player 2, ect. -->
<body gg-gamekey="{Key Assigned on App Creation}"
gg-playerkey="00000000-0000-0000-0000-000000000001"
gg-language="en">
<h1>Player Controller</h1>
<button onclick="sendMessageToHost()">Send Message to Host</button>
<button onclick="leaveGame()">Leave Game</button>
</body>
</html>
Explanation
Host Code:
- When the host page is loaded and
$GG
is ready, it callssyncPlayersToHost
to get all players who are already online. - When the
PlayerSessionSync
event is received, it adds the current waiting players to the dropdown list. - When an additional player joins (
PlayerSessionStart
), the player is added to the dropdown list, and an alert is displayed. - When a player leaves (
PlayerSessionEnd
), the player is removed from the dropdown list, and an alert is displayed. - When a player sends an action (
PlayerAction
), an alert is displayed with the player's message. - The
addPlayerToDropdown
function adds a player to the dropdown list. - The
removePlayerFromDropdown
function removes a player from the dropdown list. - The
sendMessageToPlayer
function sends a message to the selected player in the dropdown list. - The
sendMessageToPlayers
function broadcasts a message to all players.
- When the host page is loaded and
Player Controller Code:
- When the controller page is loaded and
$GG
is ready, it raises a localOnReady
event. - The connection to the server automatically causes a
PlayerSessionStart
event to be sent to the host. - It listens for
HostMessage
events and alerts the message from the host. - When the "Send Message to Host" button is clicked, it sends a
PlayerAction
event to the host. - When the browser is closed, it the connection disconnect automatically causes a
PlayerSessionEnd
event to the host.
- When the controller page is loaded and
Optional Game Engine
Game engines are optional but offer significant advantages for managing game state and enhancing communication efficiency. By running directly on Gig Games servers, game engines can preserve the game state over extended periods, independent of an active host PC. This architecture ensures continuity and enhances the gaming experience by reducing latency, as data doesn’t need to travel back and forth between the server and a host PC.
Game engines can be a more advanced topic, with a detailed discussion available here.
Third Party APIs (AJAX)
Third-party APIs can be called from both controllers and hosts in Gig Games applications. However, directly embedding API keys within JavaScript code presents a significant security risk, as it exposes the keys to potential misuse or unauthorized access.
Secure API Key Management
To mitigate this security concern, Gig Games provides a secure way to manage and use third-party API keys through the Gig Games Hud Application Editor. This approach ensures that API keys are kept secure and are not exposed in the client-side code.
How It Works
Defining API Keys:
- In the Gig Games Hud Application Editor, you can define your third-party API keys. These keys are securely stored on the Gig Games server.
Using Placeholders:
- Instead of embedding the actual API keys in your JavaScript code, you use placeholders. A placeholder is a string in the format
{YOUR_KEY_NAME}
, whereYOUR_KEY_NAME
is the name you've assigned to your API key in the Hud Application Editor.
- Instead of embedding the actual API keys in your JavaScript code, you use placeholders. A placeholder is a string in the format
Automatic Key Replacement:
- When you make an AJAX call using the
ggAjaxService
class, the Gig Games server intercepts the request. It automatically replaces the placeholders with the actual API keys stored on the server before making the call to the third-party API.
- When you make an AJAX call using the
Example:
- Suppose you have an API key named
MY_API_KEY
stored in the Hud Application Editor. You can use it in your AJAX call as follows:ajax.ajax({ url: "https://api.thirdparty.com/data?apiKey={MY_API_KEY}", method: "GET", headers: { "Content-Type": "application/json" }, data: null }).then(response => { console.log("Data received:", response); }).catch(error => { console.error("Error calling third-party API:", error); });
- When the Gig Games server receives this request, it replaces
{MY_API_KEY}
with the actual API key before forwarding the request to the third-party API.
- Suppose you have an API key named
Image Uploads
Both hosts and players in Gig Games can upload images, enhancing the interactive experience. These images are securely stored on the Gig Games server and are readily accessible to the game host for download and future use. This ensures that all uploaded images remain safe and can be easily managed by the host, contributing to a more personalized and dynamic gaming environment. The process guarantees that hosts can leverage these images effectively during gameplay, adding to the overall engagement and customization of the game.